ARD2  RC2
Airbag Reference Demonstrator using MPC5604P
MMA68xx_Diag.c
00001 
00017 #include "derivative.h" /* Contains type declarations */
00018 #include "compile_options.h"
00019 #include "MMA68xx.h"
00020 #include "HAL.h"
00021 #include "MailScheduler.h"
00022 #include "DSPI.h"
00023 #include "Utils.h"
00024 #include <limits.h> /* To set limits */
00025 #include "MMA68xx_Diag.h"
00026 /*
00027  ******************************************************************************
00028  * Constants
00029  ******************************************************************************
00030  */
00031 const uint16_t cau16MMA6800TestSettingsRaw[] =
00032 {
00033   /* Test1 & Test3, Raw data                           */
00034   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x95u),     /*Raw data*/
00035   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x09u),   /*Self test X non activated*/
00036   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x0Au)};  /*Self test Y non activated*/
00037 
00038 const uint16_t cau16MMA6800TestSettingsRawSelfX[] =
00039 {
00040   /* Test2, Raw data, Self test X                      */
00041   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x95u),     /*Raw data*/
00042   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x89u),   /*Self test X activated*/
00043   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x0Au)};  /*Self test Y non activated*/
00044   
00045 const uint16_t cau16MMA6800TestSettingsRawSelfY[] =
00046 {
00047   /* Test2, Raw data, Self test Y                      */
00048   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x95u),     /*Raw data*/
00049   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x09u),   /*Self test X non activated*/
00050   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x8Au)};  /*Self test Y activated*/
00051 
00052 const uint16_t cau16MMA6800TestSettingsOC[] =
00053 {
00054   /* Test1 & Test3, Raw data                           */
00055   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x15u),     /*Offset canceled data*/
00056   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x09u),   /*Self test X non activated*/
00057   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x0Au)};  /*Self test Y non activated*/
00058 
00059 const uint16_t cau16MMA6800TestSettingsOCSelfX[] =
00060 {
00061   /* Test2, Raw data, Self test X                      */
00062   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x15u),     /*Offset canceled data*/
00063   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x89u),   /*Self test X activated*/
00064   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x0Au)};  /*Self test Y non activated*/
00065 
00066 const uint16_t cau16MMA6800TestSettingsOCSelfY[] =
00067 {
00068   /* Test2, Raw data, Self test Y                      */
00069   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x15u),     /*Offset canceled data*/
00070   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x09u),   /*Self test X non activated*/
00071   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x8Au)};  /*Self test Y activated*/
00072 
00073 const uint32_t cau32MMA6800ErrorCodeX[] =
00074 {
00075   /* Error codes for X axis */
00076      STATUS_CA_RAW_X_FAILED, STATUS_CA_RAW_SELF_X_FAILED, STATUS_CA_RAW_HYST_X_FAILED,
00077      STATUS_CA_OC_X_FAILED, STATUS_CA_OC_SELF_X_FAILED, STATUS_CA_OC_HYST_X_FAILED};
00078 
00079 const uint32_t cau32MMA6800ErrorCodeY[] =
00080 {
00081   /* Error codes for Y axis */
00082      STATUS_CA_RAW_Y_FAILED, STATUS_CA_RAW_SELF_Y_FAILED, STATUS_CA_RAW_HYST_Y_FAILED,
00083      STATUS_CA_OC_Y_FAILED, STATUS_CA_OC_SELF_Y_FAILED, STATUS_CA_OC_HYST_Y_FAILED};
00084 
00085 const uint8_t cu8SizeofTestSettings = N_ELEMENTS(cau16MMA6800TestSettingsRaw);
00086 const uint8_t cu8SizeofTestAmount = N_ELEMENTS(cau32MMA6800ErrorCodeX);
00087 
00088 /*
00089  ******************************************************************************
00090  * u32fnMMA6800PreSelfTest
00091  ******************************************************************************
00092  */
00093 uint32_t u32fnMMA6800PreSelfTest(uint32_t* pu32Destination,
00094                                  const uint16_t* pu16DataToSend,
00095                                  const uint8_t u8Size,
00096                                  const uint8_t cu8AccelMode,
00097                                  const uint8_t cu8Axis,
00098                                  const uint16_t cu16LowLimit,
00099                                  const uint16_t cu16HighLimit,
00100                                  const uint32_t cu32StatusErrCode,
00101                                  const uint8_t cu8Accel)
00102 {
00103   /* Declare local variables */
00104   uint32_t u32Status;
00105   uint32_t u32LowLimit;
00106   uint32_t u32HighLimit;  
00107 
00108   /* Init local variables */
00109   u32Status = CLEAR;
00110 
00111   /*Limit definitions*/
00112   u32LowLimit = CA_TEST_SAMPLES_AMOUNT * cu16LowLimit;
00113   u32HighLimit = CA_TEST_SAMPLES_AMOUNT * cu16HighLimit;    
00114         
00115   /* Reading of several accelerations along cu8Axis axis*/
00116   u32Status |= u32fnMMA6800ConfigTest((uint32_t*) pu32Destination,
00117                                       (uint16_t*) pu16DataToSend,
00118                                       (uint8_t) u8Size,
00119                                       (uint8_t) cu8AccelMode,
00120                                       (uint8_t) cu8Axis,
00121                                       (uint8_t) cu8Accel);
00122     
00123   DELAY_MSEC(1u);
00124 
00125   /*Diagnostic of test*/
00126   /*Spec item 59a and 67b, for 12-bits unsigned and 105.5g sensitivity,
00127     according to Raw or OC data*/
00128     if((u32LowLimit < *pu32Destination) && (u32HighLimit > *pu32Destination))
00129     {
00130       /* Nothing to do */
00131     }
00132     else
00133     {
00134       u32Status |= cu32StatusErrCode;
00135     }
00136     return(u32Status);
00137 }
00138 /*
00139  ******************************************************************************
00140  * u32fnMMA6800PowerOnSelfTest
00141  ******************************************************************************
00142  */
00143 uint32_t u32fnMMA6800PowerOnSelfTest(uint32_t* pu32Destination,
00144                                      const uint16_t* pu16DataToSend,
00145                                      const uint16_t* pu16DataToSendCross,
00146                                      const uint8_t u8Size,                                     
00147                                      const uint8_t cu8AccelMode,
00148                                      const uint8_t cu8Axis,
00149                                      const uint32_t cu32StatusErrCode,
00150                                      const uint8_t cu8Accel)
00151 {
00152   /* Declare local variables */
00153   uint32_t u32Status;
00154   uint32_t au32FilteredSum[4];
00155   uint32_t au32CrossAxis;
00156   uint32_t au32SelfTestDeflection;
00157   uint32_t au32CrossAxisSelfTest;
00158   uint32_t u32LowLimit;
00159   uint32_t u32HighLimit;  
00160   uint32_t u32CompLimit;
00161   uint32_t u32CrossLimit;
00162 
00163   /* Init local variables */
00164   u32Status = CLEAR;
00165    
00166   /*Limit definitions*/
00167     u32LowLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_SELF_LIMIT_LO;
00168     u32HighLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_SELF_LIMIT_HI;
00169     u32CompLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_SELF_RAW_VS_OC_LIMIT;
00170     u32CrossLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_SELF_CROSS_AXIS_LIMIT;
00171    
00172     /* Reading of several accelerations along cu8Axis axis with cu8Axis self test activated */
00173     u32Status = u32fnMMA6800ConfigTest((uint32_t*) pu32Destination,
00174                                        (uint16_t*) pu16DataToSend,
00175                                        (uint8_t) u8Size,
00176                                        (uint8_t) cu8AccelMode,
00177                                        (uint8_t) cu8Axis,
00178                                        (uint8_t) cu8Accel);
00179 
00180     DELAY_MSEC(1u);
00181                 
00182     au32FilteredSum[1] = *pu32Destination;
00183     au32FilteredSum[0] = *(--pu32Destination);
00184     
00185   /****************************************** MAIN AXIS **************************************/    
00186   /*Test1*/
00187   /*Self test deflection value*/
00188   /*Spec item 90, for 105.5g sensitivity and 25°C*/
00189     au32SelfTestDeflection = au32FilteredSum[1] - au32FilteredSum[0];    
00190     if((u32LowLimit < au32SelfTestDeflection) && (u32HighLimit > au32SelfTestDeflection))
00191     {
00192       /* Nothing to do */
00193     }
00194     else
00195     {
00196       u32Status |= cu32StatusErrCode;
00197     }
00198   /*Test2*/
00199   /*Comparison of Self test deflection values for Raw and OC data */
00200   /* (Test valid for OC conf only) */
00201     if(OC_ACCEL_MODE == cu8AccelMode)
00202     {
00203       /* Go in Power On and Pre Self tests for Raw data (jump Post Self test for Raw data)*/
00204       *(--pu32Destination);
00205       *(--pu32Destination);      
00206       au32FilteredSum[3] = *pu32Destination;
00207       au32FilteredSum[2] = *(--pu32Destination);
00208       au32SelfTestDeflection = u32fnDiffAbsoluteValue((au32FilteredSum[1] - au32FilteredSum[0]),
00209                                                       (au32FilteredSum[3] - au32FilteredSum[2]));
00210       /*+-5 LSB given by Russ*/  
00211       if(au32SelfTestDeflection < u32CompLimit)
00212       {
00213         /* Nothing to do */
00214       }
00215       else
00216       {
00217         u32Status |= cu32StatusErrCode;
00218       }
00219     }        
00220   /*************************************** CROSS AXIS ****************************************/       
00221   /* Reading of several accelerations along cu8Axis axis cross axis self test activated */
00222     u32Status |= u32fnMMA6800ConfigTest((uint32_t*) &au32CrossAxis,
00223                                         (uint16_t*) pu16DataToSendCross,
00224                                         (uint8_t) u8Size,
00225                                         (uint8_t) cu8AccelMode,
00226                                         (uint8_t) cu8Axis,
00227                                         (uint8_t) cu8Accel);
00228 
00229        DELAY_MSEC(1u);
00230                    
00231     au32FilteredSum[1] = au32CrossAxis;
00232        
00233     /*Test3*/
00234     /*Self test cross axis, spec item 96 and 97*/
00235     au32CrossAxisSelfTest = u32fnDiffAbsoluteValue(au32FilteredSum[1], au32FilteredSum[0]);       
00236     if(u32CrossLimit > au32CrossAxisSelfTest)
00237     {
00238       /* Nothing to do */
00239     }
00240     else
00241     {
00242       u32Status |= cu32StatusErrCode;
00243     }
00244 
00245     return(u32Status);
00246 }
00247 /*
00248  ******************************************************************************
00249  * u32fnMMA6800PostSelfTest
00250  ******************************************************************************
00251  */
00252 uint32_t u32fnMMA6800PostSelfTest(uint32_t* pu32Destination,
00253                                   const uint16_t* pu16DataToSend,
00254                                   const uint8_t u8Size,                                  
00255                                   const uint8_t cu8AccelMode,
00256                                   const uint8_t cu8Axis,
00257                                   const uint32_t cu32StatusErrCode,
00258                                   const uint8_t cu8Accel)
00259 {
00260   /* Declare local variables */
00261   uint32_t u32Status;
00262   uint32_t au32FilteredSum[2];
00263   uint32_t au32PostSelfTest;
00264   uint32_t u32LowLimit;
00265   uint32_t u32HighLimit;  
00266   uint32_t u32HystLimit;
00267 
00268   /* Init local variables */
00269   u32Status = CLEAR;
00270   
00271   /*Limit definitions*/    
00272     u32LowLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_OC_LIMIT_LO;
00273     u32HighLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_OC_LIMIT_HI;    
00274     u32HystLimit = CA_TEST_SAMPLES_AMOUNT * CA_TEST_RAW_LIMIT_HYST;
00275         
00276     /* Reading of several accelerations along cu8Axis axis*/
00277     u32Status |= u32fnMMA6800ConfigTest((uint32_t*) pu32Destination,
00278                                         (uint16_t*) pu16DataToSend,
00279                                         (uint8_t) u8Size,
00280                                         (uint8_t) cu8AccelMode,
00281                                         (uint8_t) cu8Axis,
00282                                         (uint8_t) cu8Accel);
00283     
00284     DELAY_MSEC(1u);
00285     
00286     au32FilteredSum[1] = *(pu32Destination--);
00287     au32FilteredSum[0] = *(--pu32Destination);   
00288     
00289     /*Diagnostic of test according to Raw or OC data*/
00290     if(RAW_ACCEL_MODE == cu8AccelMode)
00291     {
00292       au32PostSelfTest = u32fnDiffAbsoluteValue(au32FilteredSum[0], au32FilteredSum[1]);
00293       if(u32HystLimit > au32PostSelfTest)
00294       {
00295         /* Nothing to do */
00296       }
00297       else
00298       {
00299         u32Status |= cu32StatusErrCode;
00300       }
00301     }
00302     else if (OC_ACCEL_MODE == cu8AccelMode)
00303     {
00304       if((u32LowLimit < au32FilteredSum[1]) && (u32HighLimit > au32FilteredSum[1]))
00305       {
00306         /* Nothing to do */
00307       }
00308       else
00309       {
00310         u32Status |= cu32StatusErrCode;
00311       }
00312     }
00313     return(u32Status);
00314 }
00315 /*
00316  ******************************************************************************
00317  * u32fnMMA6800ConfigTest
00318  ******************************************************************************
00319  */
00320 uint32_t u32fnMMA6800ConfigTest(uint32_t* pu32Destination,
00321                                 const uint16_t* pu16DataToSend,
00322                                 const uint8_t u8Size,
00323                                 const uint8_t u8AccelMode,
00324                                 const uint8_t u8Axis,
00325                                 const uint8_t cu8Accel)
00326 {
00327   /* Declare local variables */
00328   uint32_t u32Status;
00329   uint8_t u8Status;
00330 
00331   /* Init local variables */
00332   u32Status = CLEAR;
00333   u8Status = CLEAR;  
00334    
00335   /*CA configuration*/    
00336     u8Status = ((*u8pfnMMA6800BatchOp[MMA6800_TRANSFER_MODE_IS_SCHEDULED])
00337                 (MAIN_ACCELERO_SPI_CONFIG,( uint16_t*)pu16DataToSend,
00338                 (uint16_t*)gau8MMA6800GlobalResult,
00339                 (uint8_t)u8Size));
00340     
00341     DELAY_MSEC(5u);
00342     
00343   /*Reading of several acceleration data*/    
00344     u32Status = u32fnMMA6800ReadAccelSum((uint8_t) u8Axis, (uint8_t) u8AccelMode, 
00345                                          (uint32_t*) pu32Destination, cu8Accel);    
00346     
00347     DELAY_MSEC(1u);
00348     
00349     return(u32Status);
00350 }
00351 /*
00352  ******************************************************************************
00353  * u32fnMMA6800ReadAccelSum
00354  ******************************************************************************
00355  */
00356 uint32_t u32fnMMA6800ReadAccelSum(const uint8_t u8Axis,
00357                                   const uint8_t u8AccelMode,
00358                                   uint32_t* pu32Destination,
00359                                   const uint8_t cu8Accel)
00360 {
00361   /* Declare local variables */
00362   uint32_t u32Status;
00363   uint8_t  u8Status;  
00364   uint16_t u16Counter;
00365   uint32_t au32TempResults[CA_TEST_SAMPLES_AMOUNT]= {CLEAR};
00366   uint16_t au16RawResult[2u];
00367   uint16_t au16Filtered;
00368   uint32_t u32Time0;
00369 
00370   
00371   /* Init local variables */
00372   u32Status = CLEAR;
00373   u8Status = CLEAR;
00374   u16Counter = CLEAR;
00375   *pu32Destination = CLEAR;
00376   
00377   for(u16Counter = CLEAR; u16Counter < CA_TEST_SAMPLES_AMOUNT; u16Counter++)
00378   {  
00379     u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 
00380                                     MMA6800_TRANSFER_MODE_IS_SCHEDULED, 
00381                                     u8Axis,
00382                                     u8AccelMode,
00383                                     (uint16_t*)&au32TempResults[u16Counter],
00384                                     cu8Accel);
00385 
00386     SCHED_WHAT_IS_THE_TIME(u32Time0);
00387     /* Wait for signal to be sent to the SBC */
00388     while(3u > u32fnSchedHasTimeElapsed(u32Time0))
00389     {
00390       /* Wait here */
00391     };
00392     
00393     if(CLEAR < u8Status)
00394     {
00395       u32Status |= STATUS_CA_FAILED;
00396     }
00397     else
00398     {
00399       /* Nothing to do */
00400     }    
00401   } 
00402   
00403   if (CLEAR == u32Status)
00404   {
00405     for(u16Counter = CLEAR; u16Counter < CA_TEST_SAMPLES_AMOUNT; u16Counter++)
00406     {    
00407       u32Status |= u8fnMMA6800ExtractAccelResponse((uint16_t*)&au32TempResults[u16Counter],
00408                                                    (uint16_t*)au16RawResult,
00409                                                    RAW_MMA_ACCEL_ARRAY_SIZE - 1u,
00410                                                    cu8Accel);
00411       au16Filtered = au16RawResult[1u];
00412       *pu32Destination += au16Filtered;
00413     }
00414   }
00415   else
00416   {
00417     /* Nothing to do */
00418   }  
00419   return(u32Status);
00420 }
00421 
00422 /*
00423  ******************************************************************************
00424  *
00425  *  End of file.
00426  *
00427  ******************************************************************************
00428  */